時間

您所在的位置:网站首页 perl timelocal 時間

時間

#時間| 来源: 网络整理| 查看: 265

時間 ■ 現在の日付・時刻を得る(time, gmtime, localtime) ◆ 現在の日付・時刻を得る

time() は、グリニッジ標準時 1970年1月1日0時0分0秒を 0 とした現時刻の秒数を返します。gmtime()localtime() はこの時刻を年、月、日、時、分、秒に分解します。gmtime() はグリニッジ標準時における値を、localtime() は現地時刻の値を返します。

$ENV{'TZ'} = "JST-9"; @wdays = ( "日", "月", "火", "水", "木", "金", "土"); $time = time(); ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime($time); printf("%04d/%02d/%02d %02d:%02d:%02d(%s)\n", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $wdays[$wday]);

実行結果は次のようになります。

2002/02/11 01:13:59(月) ◆ 年と月の注意

$year には 1900 年からの差分が返されます。また、$mon には月から 1 を引いた値(0~11)が返されますので注意してください。

◆ タイムゾーン

プログラムの最初の方で $ENV{'TZ'} を設定しておかないと、時間帯が狂うことがあります。"JST-9" は「日本時間、標準時から -9 時間のずれ」を意味しています。例えば、アメリカ東部標準時間(EST)での時刻を求めるには次のようにします。

$ENV{'TZ'} = "EST+5"; @wdays = ( "日", "月", "火", "水", "木", "金", "土"); $time = time(); ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime($time); printf("%04d/%02d/%02d %02d:%02d:%02d(%s)\n", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $wdays[$wday]);

ただし、システムによっては、環境変数 TZ の値を参照しないものもあるようです。

■ ファイルの最終更新時刻を得る ◆ ファイルの作成日付を得る

stat() や lstat() を用いて、ファイルの最終更新時刻を得ることができます。返される時間は 1970年1月1日からの秒数なので、localtime() を用いて年月日時分秒に分解します。

$ENV{'TZ'} = "JST-9"; @wdays = ( "日", "月", "火", "水", "木", "金", "土"); $mtime = (stat("file.txt"))[9]; ($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime($mtime); printf("%04d/%02d/%02d %02d:%02d:%02d(%s)\n", $year + 1900, $mon + 1, $mday, $hour, $min, $sec, $wdays[$wday]);

実行結果は次のようになります。

2002/02/11 01:16:50(月) ■ 閏年かどうか調べる ◆ 閏年かどうか調べる

閏年(うるうどし)は西暦が4で割りきれる年です。ただし、100で割りきれる年は閏年ではありません。ただし、400で割りきれるときは閏年となります。

sub IsLeapYear { local($year) = @_; if (($year % 400) == 0) { return 1; } if (($year % 100) == 0) { return 0; } if (($year % 4) == 0) { return 1; } return 0; } for ($year = 1998; $year < 2002; $year++) { if (IsLeapYear($year)) { print "$year年は閏年です。\n"; } else { print "$year年は閏年ではありません。\n"; } }

実行結果は次のようになります。2000年は 100でも割り切れますが、400でも割り切れるので閏年となります。

1998年は閏年ではありません。 1999年は閏年ではありません。 2000年は閏年です。 2001年は閏年ではありません。 ■ 1970年1月1日からの秒数を求める ◆ Time::Local の timelocal を用いる例

localtime() とは逆に、現地時刻の年、月、日、時、分、秒から、グリニッジ標準時 1970年1月1日0時0分0秒からの秒数を求めるには、Time::Local モジュールの timelocal() を用います。

use Time::Local; $year = 1999; $mon = 12; $mday = 31; # 1999年12月31日 $hour = 23; $min = 59; $sec = 59; # 23時59分59秒 $time = timelocal($sec, $min, $hour, $mday, $mon - 1, $year - 1900); print "$time\n";

結果は次のようになります。

946652399

$year は 1900年からの差分、$mon は 0~11 の値で指定するので注意してください。

◆ POSIX の mktime を用いる例

POSIX モジュールの mktime() を用いても同じことができます。

use POSIX; $year = 1999; $mon = 12; $mday = 31; # 1999年12月31日 $hour = 23; $min = 59; $sec = 59; # 23時59分59秒 $time = mktime($sec, $min, $hour, $mday, $mon - 1, $year - 1900); print "$time\n";

結果は次のようになります。

946652399 ■ 時刻の差分を求める ◆ 時刻の差分を求める

1992年4月11日12時34分56秒は、2002年12月31日19時45分12秒の何日と何時間前でしょうか。このような時刻の差分を計算する場合、両者を一度1970年1月1日からの秒数に変換し、この差分を求めることで計算できます。

use Time::Local; # 両者を一度 1970/01/01 00:00:00 からの秒数に変換する $t1 = timelocal(56, 34, 12, 11, 4 - 1, 1992 - 1900); $t2 = timelocal(12, 45, 19, 31, 12 - 1, 2002 - 1900); $diff = $t2 - $t1; # 秒数の差分を求める $days = int($diff / (3600 * 24)); # 日数を求める $diff %= (3600 * 24); $hours = int($diff / 3600); # 時間を求める $diff %= 3600; $minutes = int($diff / 60); # 分を求める $diff %= 60; $secs = $diff; # 秒数を求める print "$days日$hours時間$minutes分$secs秒前です。\n";

結果は次のようになります。

3916日7時間10分16秒前です。 ■ 指定した日付の曜日を求める ◆ 指定した日付の曜日を求める

Zellerの公式 を用いて、指定した日付の曜日を求めます。0 が日曜日、6 が土曜日になります。これは、1583年~3999年までの間で有効な公式だそうです。前出の mktime() や timelocal() を用いて1970年からの秒数を求め、これを localtime() にかけても算出できます。

@wdays = ( "日", "月", "火", "水", "木", "金", "土"); sub GetDate { local($yy, $mm, $dd) = @_; if (($mm == 1) || ($mm == 2)) { $yy--; $mm += 12; } return ($yy + int($yy / 4) - int($yy / 100) + int($yy / 400) + int(2.6 * $mm + 1.6) + $dd) % 7; } print "2001/12/31 は" . $wdays[GetDate(2001, 12, 31)] . "曜日です\n"; ■ 指定した時間待つ(sleep, select) ◆ sleep()を用いる方法

sleep() は指定した秒数だけ処理をスリープ(中断)して待ちます。例では、"A" を 1秒毎に10個書き出します。

for ($i = 0; $i < 10; $i++) { print "A\n"; sleep(1); } ◆ select()を用いる方法

select() を用いることにより、待ち時間をミリ秒の単位で指定することができます。例では、"B" を 0.5秒毎に 10個書き出します。

for ($i = 0; $i < 10; $i++) { print "B\n"; select(undef, undef, undef, 0.5); } ■ プロセスが消費した時間を調べる(times) ◆ プロセスが消費した時間を調べる

times() は、プロセスや子プロセスが消費したユーザCPU時間とシステムCPU時間を秒単位で返します。

($user1, $system1, $c_user1, $c_system1) = times(); for ($i = 0; $i < 10; $i++) { system("netstat -a"); } ($user2, $system2, $c_user2, $c_system2) = times(); printf("ユーザ時間:%5.3f秒\n", $user2 - $user1); printf("システム時間:%5.3f秒\n", $system2 - $system1); printf("子プロセスユーザ時間:%5.3f秒\n", $c_user2 - $c_user1); printf("子プロセスシステム時間:%5.3f秒\n", $c_system2 - $c_system1);

実行結果は次のようになります。(結果表示部分のみ)

ユーザ時間:0.016秒 システム時間:0.016秒 子プロセスユーザ時間:0.000秒 子プロセスシステム時間:0.000秒

この値を測定することにより、プロセスがどのくらい、CPU に負荷をかけているかを計測することが可能になり、システム高速化検討の目安となります。

■ パフォーマンスを調べる ◆ パフォーマンスを調べる

stat() と lstat() はどちらの方がどのくらいパフォーマンスがよいでしょうか。stat() や lstat() の処理時間を測定できればよいのですが、処理の前後で time() を取得して差分をとっても、大抵が 0 秒となってうまく計測できません。この場合、処理を繰り返して差分が発生する確率を求めることにより、パフォーマンスの推定を可能にする方法が考えられます。

open(IN, "data.txt"); for ($i = 0; $i < 10000; $i++) { $t1 = time(); lstat(IN); # 処理1 $t2 = time(); stat("stat.txt"); # 処理2 $t3 = time(); $tt1 += ($t2 - $t1); # 処理1に要した時間の合計 $tt2 += ($t3 - $t2); # 処理2に要した時間の合計 } close(IN); print "処理1 = $tt1\n"; print "処理2 = $tt2\n";

実行結果の例は例えば次のようになります。

処理1 = 2 処理2 = 16

結果からは、処理1(lstat)よりも処理2(stat)の方が、8倍も遅いことが分ります。結果に差異が現れない場合は、ループの回数(例では 10000)を増やしてみてください。

Copyright (C) 2002 杜甫々


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3